#pragma once

template <class T, size_t MAX_OBJECTS>
class Pool
{
public:

	Pool()
	:	m_firstFree(0)
	,	m_numAllocated(0)
	{
		T* pObj = (T*)m_memory;
		for (size_t i = 0; i < MAX_OBJECTS; ++i, ++pObj)
		{
			if (i < (MAX_OBJECTS-1))
				*((cr::uint32_t*)pObj) = i+1;
			else
				*((cr::uint32_t*)pObj) = 0xffffffff;
		}
	}

	T* Allocate()
	{
		CR_ASSERT(m_firstFree != 0xffffffff);
		T* pRes = ((T*)m_memory) + m_firstFree;
		m_firstFree = *((cr::uint32_t*)pRes);
		new (pRes) T;
		m_numAllocated++;
		return pRes;
	}

	void Free(T* pObj)
	{
		CR_ASSERT(pObj >= (T*)m_memory && pObj < ((T*)m_memory)+MAX_OBJECTS);
		pObj->~T();
		*((cr::uint32_t*)pObj) = m_firstFree;
		m_firstFree = (pObj-((T*)m_memory));
		m_numAllocated--;
	}

private:

	cr::uint8_t		m_memory[MAX_OBJECTS*sizeof(T)];
	cr::uint32_t	m_firstFree;
	cr::uint32_t	m_numAllocated;
};